﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
using WaffleControl.Types;
using WaffleControl;
using Windows.Graphics.Display;
using Windows.UI.ViewManagement;


// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace WaffleControl
{
    namespace Types
    {
        public delegate void WaffleListCallback(WaffleListItem i, object view);
        public struct WaffleListItem
        {
            #region hidden
            public object Custom { get; set; }
            public WaffleListCallback Callback { get; set; }
            #endregion
            #region visual
            public string Text { get; set; }
            public string Path { get; set; }
            #endregion
        }
    }

    public sealed partial class WaffleBar : UserControl
    {
        #region dependency
        #region styles



        public Brush WaffleButtonForeground
        {
            get { return (Brush)GetValue(WaffleButtonForegroundProperty); }
            set { SetValue(WaffleButtonForegroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleButtonForeground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleButtonForegroundProperty =
            DependencyProperty.Register("WaffleButtonForeground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.WhiteSmoke)));

        

        /// <summary>
        /// Waffle button's background
        /// </summary>
        public Brush WaffleButtonBackground
        {
            get { return (Brush)GetValue(WaffleButtonBackgroundProperty); }
            set { SetValue(WaffleButtonBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleButtonBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleButtonBackgroundProperty =
            DependencyProperty.Register("WaffleButtonBackground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.CornflowerBlue)));

        

        /// <summary>
        /// Waffle content tile foreground
        /// </summary>
        public Brush WaffleTileForeground
        {
            get { return (Brush)GetValue(WaffleTileForegroundProperty); }
            set { SetValue(WaffleTileForegroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleTileBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleTileForegroundProperty =
            DependencyProperty.Register("WaffleTileForeground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.White)));

        /// <summary>
        /// Waffle content tile background
        /// </summary>
        public Brush WaffleTileBackground
        {
            get { return (Brush)GetValue(WaffleTileBackgroundProperty); }
            set { SetValue(WaffleTileBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleTileBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleTileBackgroundProperty =
            DependencyProperty.Register("WaffleTileBackground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.SteelBlue)));

        
        /// <summary>
        /// Waffle content background
        /// </summary>
        public Brush WaffleMenuContentBackground
        {
            get { return (Brush)GetValue(WaffleMenuContentBackgroundProperty); }
            set { SetValue(WaffleMenuContentBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleMenuContentBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleMenuContentBackgroundProperty =
            DependencyProperty.Register("WaffleMenuContentBackground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.White)));

        
        /// <summary>
        /// waffle bar items foreground
        /// </summary>
        public Brush BottomListItemsForeground
        {
            get { return (Brush)GetValue(BottomListItemsForegroundProperty); }
            set { SetValue(BottomListItemsForegroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BottomListItemsForeground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BottomListItemsForegroundProperty =
            DependencyProperty.Register("BottomListItemsForeground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.WhiteSmoke)));

        

        /// <summary>
        /// Waffle bar background
        /// </summary>
        public Brush BarBackground
        {
            get { return (Brush)GetValue(BarBackgroundProperty); }
            set { SetValue(BarBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BarBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BarBackgroundProperty =
            DependencyProperty.Register("BarBackground", typeof(Brush), typeof(WaffleBar), new PropertyMetadata(new SolidColorBrush(Windows.UI.Colors.SteelBlue)));

        
        #endregion
        /// <summary>
        /// Contains the bar list buttons
        /// </summary>
        public ObservableCollection<WaffleListItem> BarListItems
        {
            get { return (ObservableCollection<WaffleListItem>)this.GetValue(BarListItemsProperty); }
            set { this.SetValue(BarListItemsProperty, value); }
        }

        public static readonly DependencyProperty BarListItemsProperty =
            DependencyProperty.Register("BarListItems", typeof(ObservableCollection<WaffleListItem>), typeof(WaffleBar), new PropertyMetadata(null));
        /// <summary>
        /// The height of waffle opened container
        /// </summary>
        public double ContainerHeight
        {
            get { return (double)GetValue(ContainerHeightProperty); }
            set { SetValue(ContainerHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ContainerHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContainerHeightProperty =
            DependencyProperty.Register("ContainerHeight", typeof(double), typeof(WaffleBar), new PropertyMetadata(400.0));

        /// <summary>
        /// The waffle tile button size 
        /// </summary>
        public double WaffleTileSize
        {
            get { return (double)GetValue(WaffleTileSizeProperty); }
            set { SetValue(WaffleTileSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaffleTileSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleTileSizeProperty =
            DependencyProperty.Register("WaffleTileSize", typeof(double), typeof(WaffleBar), new PropertyMetadata(150));

        /// <summary>
        /// Gridview menu items collection
        /// </summary>
        public ObservableCollection<WaffleListItem> WaffleTileListItems
        {
            get { return (ObservableCollection<WaffleListItem>)GetValue(WaffleTileListItemsProperty); }
            set { SetValue(WaffleTileListItemsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ListContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaffleTileListItemsProperty =
            DependencyProperty.Register("WaffleTileListItems", typeof(ObservableCollection<WaffleListItem>), typeof(WaffleBar), new PropertyMetadata(null));


        /// <summary>
        /// Indicate if on tablet the Gridview content must be resized
        /// NOTE: Only for WINDOWS APP
        /// </summary>
        public bool ReduceForAppPortait
        {
            get { return (bool)GetValue(ReduceForAppPortaitProperty); }
            set { SetValue(ReduceForAppPortaitProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ReduceForAppPortait.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ReduceForAppPortaitProperty =
            DependencyProperty.Register("ReduceForAppPortait", typeof(bool), typeof(WaffleBar), new PropertyMetadata(true));

        

        #endregion
        #region controls properties
        private double FirstHeight = 0.0;
        #endregion


        public WaffleBar()
        {
            this.InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Storyboard s;
            if (this.WaffleContent.Visibility == Visibility.Visible)
            {
                s = (Storyboard)this.WaffleContent.Resources["WaffleContentOut"];
                s.Completed += new EventHandler<object>(
                    (object origin, object evt) => 
                    { 
                        this.WaffleContent.Visibility = Visibility.Collapsed; 
                        this.ContentRow.Height = new GridLength(0);
                    });
            }
            else
            {
                s = (Storyboard)this.WaffleContent.Resources["WaffleContentIn"];
                this.WaffleContent.Visibility = Visibility.Visible;
                this.ContentRow.Height = new GridLength(this.ContainerHeight - this.WaffleBarContainer.ActualHeight);
            }
            s.Begin();
        }
        /// <summary>
        /// When the layout size change (with orientation)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SizeChangedEvent(object sender, SizeChangedEventArgs e)
        {
 #if WINDOWS_PHONE_APP           
            //if wp, we need to change de grid content alignment
            if(this.IsPortait())
            {
                this.WaffleContentGridView.HorizontalAlignment = HorizontalAlignment.Center;
            }
            else
            {
                this.WaffleContentGridView.HorizontalAlignment = HorizontalAlignment.Left;
            }
#endif
#if WINDOWS_APP
            if (this.ReduceForAppPortait && this.FirstHeight > 0)
                this.WaffleContent.Width = this.MainWaffleContent.ActualWidth / (this.IsPortait() ? 2 : 4);
            else//if not want reduce, here we remove the margin with the -20
                this.WaffleContent.Width = this.MainWaffleContent.ActualWidth - 20;
            //if windows app, when the orientation changes we can
            if (this.IsPortait() && this.FirstHeight > 0)
            {
                //If reduce for app portait is true (default) we set the containerheight to the half size
               if (this.ContainerHeight >= this.FirstHeight && this.ContainerHeight > 300 && this.ReduceForAppPortait)
               {
                   this.ContainerHeight = this.ContainerHeight / 2;
               }
            }
            
#endif
            if (this.WaffleContent.Visibility == Visibility.Visible)
                this.ContentRow.Height = new GridLength(this.ContainerHeight - this.WaffleBarContainer.ActualHeight);
        }
        /// <summary>
        /// Check the display orientation
        /// </summary>
        /// <returns></returns>
        private bool IsPortait()
        {
            return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Portrait;
        }
        #region listitems events
        private void BottomListClick(object sender, ItemClickEventArgs e)
        {
            WaffleListItem ListItem = (WaffleListItem)e.ClickedItem;
            if (ListItem.Callback != null)
                ListItem.Callback(ListItem,(object)this);
        }

        private void TopListClick(object sender, ItemClickEventArgs e)
        {
            WaffleListItem ListItem = (WaffleListItem)e.ClickedItem;
            if (ListItem.Callback != null)
                ListItem.Callback(ListItem, (object)this);
        }
        #endregion
        /// <summary>
        /// When control is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private new void Loaded(object sender, RoutedEventArgs e)
        {

            this.FirstHeight = this.ContainerHeight;
#if WINDOWS_APP
            if (this.ReduceForAppPortait)
                this.WaffleContent.Width = this.MainWaffleContent.ActualWidth / (this.IsPortait() ? 2 : 4);
            else//if not want reduce, here we remove the margin with the -20
                this.WaffleContent.Width = this.MainWaffleContent.ActualWidth - 20;
            this.WaffleContent.HorizontalAlignment = HorizontalAlignment.Left;
            this.WaffleContentGridView.HorizontalAlignment = HorizontalAlignment.Left;
#endif
        }
    }
}
